package com.cjl.demo.thread;

import java.util.concurrent.TimeUnit;

/**
 * <p>Description: 程序在执行过程中，如果出现异常，默认情况锁会被释放</p>
 *
 * @ uthor chenjinliang
 * @ date: 2020/5/22
 */
public class Demo11 {

    int count = 0;

    /**
     *
     * 程序在执行过程中，如果出现异常，默认情况锁会被释放
     * 所以，在并发处理的过程中，有异常要多加小心，不然可能会发生不一致的情况
     * 比如，在一个web app处理过程中，多个servlet线程共同访问通一个资源，这是如果异常处理不合适
     *  在第一个线程中抛出异常，其他线程就会进入同步代码去，有可能访问到异常产生是的数据
     *  因此要非常小心的处理同步业务逻辑中的异常
     */
    synchronized void test() throws Exception{
        System.out.println(Thread.currentThread().getName() + " start......");
        while (true) {
            count ++;
            System.out.println(Thread.currentThread().getName() + " count = " + count);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (count == 5) {
                //TODO 如果写成1/0，会使编译奔溃，线上查暂时没有找到明确的说明，按理说这种应该抛出异常
//                try {
                    long t1 = 1L;
                    Long t2 = null;
                    long t = (t1 == 2L? t1 : t2);
//                    int i = 1/(5-count); //此处抛出异常，锁将被释放，要想不被释放，可以在这里进行catch处理，然后让循环继续
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
            }
        }
    }
    public static void main(String[] args) {
        Demo11 demo11 = new Demo11();
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    demo11.test();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        new Thread(r, "t1").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(r, "t2").start();
    }
}
